package com.liqing.movecomment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liqing.movecomment.dao.CommentDao;
import com.liqing.movecomment.dao.UserDao;
import com.liqing.movecomment.entity.Comment;
import com.liqing.movecomment.entity.User;
import com.liqing.movecomment.enums.RedisConstant;
import com.liqing.movecomment.service.CommentService;
import com.liqing.movecomment.util.RedisUtils;
import com.liqing.movecomment.util.SwapePageUtil;
import com.liqing.movecomment.util.ThreadLocalUtils;
import com.liqing.movecomment.vo.*;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


@Service
@Transactional
public class CommentServiceImpl
        implements CommentService {


    @Resource
    private CommentDao commentDao;

    @Resource
    private UserDao userDao;


    @Override
    public PageInfo<CommentRootVo> listAllComments(Long videoId, int size, int current) {

        List<CommentRootVo> list = new ArrayList<>();
        Page<Comment> commentPage = new Page<>(current, size);
        LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Comment::getRoot, "0").eq(Comment::getParent, "0").eq(Comment::getOtherId, videoId);

        final Page<Comment> page = commentDao.selectPage(commentPage, wrapper);

        List<String> collect = page.getRecords().stream().map(Comment::getId).map((id) -> {

            return String.valueOf(id);
        }).collect(Collectors.toList());
        for (String rooId :
                collect) {
            list.add(listComments(rooId));
        }

        final PageInfo<CommentRootVo> pageInfo = new PageInfo<>();


        BeanUtils.copyProperties(page, pageInfo);
        pageInfo.setList(list);

        return SwapePageUtil.swapePage(collect, list);
    }

    @Override
    public Boolean deleteById(Integer id) {

      User user =(User)  ThreadLocalUtils.get();
        Integer userId = user.getId();

        //1、判断是不是一级评论
         Comment comment = commentDao.selectById(id);
        if(comment.getParent().equals("0") && comment.getRoot().equals("0")){
            //是一级评论删除所有的评论

             commentDao.delete(new LambdaQueryWrapper<Comment>().eq(Comment::getRoot,comment.getId())) ;
        }else {
            //不是一级评论 删除所有的 parent是 id的评论
    commentDao.delete(new LambdaQueryWrapper<Comment>().eq(Comment::getParent,id));        }
        //删除评论点赞


        String likeKeySet = RedisConstant.move.COMMENT.LIKE_SET + id;
        RedisUtils.removeSetKey(likeKeySet, String.valueOf(userId));

        return commentDao.deleteById(id) > 0;

    }

    @Override
    public CommentRootVo listComments(String rootId) {
        //1、先拼装 replies
        /*
         *
         *
         * */
        CommentRootVo commentRootVo = new CommentRootVo();


        List<Reply> replies = new ArrayList<>();

        List<Comment> commentList = commentDao.selectAllByRoot(rootId);

        for (Comment comment : commentList
        ) {
            Reply reply = createReply(comment);
            replies.add(reply);
            commentRootVo.setCount(commentRootVo.getCount() + 1);
        }
        commentRootVo.setReplies(replies);

        /*
         * 1、如果是一级评论就要拼接root
         *
         * */


        Root root = createRoot(rootId);
        commentRootVo.setRoot(root);
        return commentRootVo;
    }


    @Override
    public MessageVo save(CommentPostVo commentPostVo) {


        User user = (User) ThreadLocalUtils.get();
        commentPostVo.setReplyId(user.getId());

        Comment comment = new Comment();
        comment.setOtherId(commentPostVo.getOtherId());
        /*
         * level设置
         * 如果 parent 和root = 0则 level 为0，一级评论
         * 否则 查询 当前parent 相同的有多少，然后 +1
         * */
        if (commentPostVo.getParent().equals("0")) {
            comment.setLevel(0);
        } else {
            int levelAll = commentDao.selectCountByParentId(commentPostVo.getParent());
            comment.setLevel(levelAll + 1);
        }
        comment.setRoot(commentPostVo.getRoot());
        comment.setMessage(commentPostVo.getMessage());
        comment.setParent(commentPostVo.getParent());
        comment.setReplyedId(commentPostVo.getReplyedId());
        comment.setReplyId(commentPostVo.getReplyId());
        commentDao.insert(comment);


        //组装返回数据
        Comment commentreturn = commentDao.selectById(comment.getId());
        if (Objects.isNull(commentreturn)) {
            throw new RuntimeException("发布评论失败");
        }
        MessageVo messageVo = new MessageVo();
        messageVo.setId(commentreturn.getId());
        messageVo.setOtherId(commentreturn.getOtherId());
        messageVo.setRoot(commentreturn.getRoot());
        messageVo.setParent(commentreturn.getParent());
        messageVo.setReplyId(commentreturn.getReplyId());

        messageVo.setReply(createReply(commentreturn));

        return messageVo;
    }


    @Override
    public PageInfo< AnswerMeVo> anwserMe(Integer page, Integer size) {

        PageHelper.startPage(page, size);
        User user = (User) ThreadLocalUtils.get();
        Integer userId = user.getId();
        List<Comment> comments = commentDao.selectList(new LambdaQueryWrapper<Comment>().eq(Comment::getReplyedId, userId).ne(Comment::getReplyId,userId));

        List<AnswerMeVo> answerMeVoList = new ArrayList<>();
        comments.stream().parallel().forEach(comment ->{
            final AnswerMeVo answerMeVo = new AnswerMeVo();

            Reply reply = createReply(comment);
            answerMeVo.setReply(reply);

            answerMeVo.setMyComment(   commentDao.selectById(reply.getParent()).getMessage());

            answerMeVoList.add(answerMeVo);

        });






        return SwapePageUtil.swapePage(comments,answerMeVoList);
    }

    private Root createRoot(String rootId) {

        Comment comment = commentDao.selectById(rootId);
        Root root = new Root();

        root.setId(Integer.valueOf(rootId));
        root.setRoot(comment.getRoot());
        root.setParent(comment.getParent());
        root.setOtherId(comment.getOtherId());
        root.setReplyId(comment.getReplyId());

        root.setMember(createUserReply(comment.getReplyId()));

        Content content = new Content();
        content.setMessage(comment.getMessage());

        root.setContent(content);


        root.setCreateTime(comment.getCreateTime());
        Long likeCount = 0L;
        Boolean isLike = false;


        //判断 单条 评论里面的内容是否 点赞 以及  点赞数量

        String key = RedisConstant.move.COMMENT.LIKE_SET + rootId;

        if (RedisUtils.hasKey(key)) {
            likeCount = RedisUtils.getSetCount(key);
            User user = (User) ThreadLocalUtils.get();
            isLike = RedisUtils.isSetHas(key, String.valueOf(user.getId()));

        }


        root.setLikeCount(likeCount);
        root.setIsLike(isLike);


        return root;
    }


    private Reply createReply(Comment commentreturn) {
        Reply reply = new Reply();
        reply.setId(commentreturn.getId());
        reply.setOtherId(commentreturn.getOtherId());
        reply.setCreateTime(commentreturn.getCreateTime());
        reply.setRoot(commentreturn.getRoot());
        reply.setParent(commentreturn.getParent());
        reply.setReplyId(commentreturn.getReplyId());

        /*
         * 组装 reply的 评论数量 以及 自己是否评论
         * */
        Long likeCount = 0L;
        Boolean isLike = false;


        //判断 单条 评论里面的内容是否 点赞 以及  点赞数量

        String key = RedisConstant.move.COMMENT.LIKE_SET + reply.getId();

        if (RedisUtils.hasKey(key)) {
            likeCount = RedisUtils.getSetCount(key);
            User user = (User) ThreadLocalUtils.get();
            isLike = RedisUtils.isSetHas(key, String.valueOf(user.getId()));

        }


        reply.setLikeCount(likeCount);
        reply.setIsLike(isLike);


        /*
         * 如果不是1级评论，就设置子类的 members
         * */
        Content content = null;
        if (!commentreturn.getParent().equals("0") && !commentreturn.getRoot().equals("0")) {
            content = createContent(commentreturn.getReplyedId());
            content.getMembers().get(0).setCurrent_level(commentDao.selectById(commentreturn.getParent()).getLevel());

        } else {
            content = new Content();
        }


        content.setMessage(commentreturn.getMessage());


        reply.setContent(content);


        //设置当前的评论的level
        final UserReply userReply = createUserReply(commentreturn.getReplyId());
        userReply.setCurrent_level(commentreturn.getLevel());
        reply.setMember(userReply);

        return reply;
    }

    /*
     * 被评论的id
     * */
    private Content createContent(Integer replyedId) {
        final Content content = new Content();

        final ArrayList<UserReply> userReplies = new ArrayList<>();
        final UserReply userReply = createUserReply(replyedId);
        userReplies.add(userReply);
        content.setMembers(userReplies);
        content.setAt_name_to_mid(new at_name_to_mid(userReply.getUsername(), Math.toIntExact(userReply.getId())));

        return content;

    }


    private UserReply createUserReply(Integer id) {


        User sysUser = userDao.selectById(id);


        UserReply userReply = new UserReply();
        userReply.setUsername(sysUser.getName());
        userReply.setAvatar(sysUser.getAvatar());
        userReply.setId(Long.valueOf(id));
        return userReply;
    }
}




